package pl.iachoo.ctl.tabory.ui.editors.compositions.composites;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

import pl.iachoo.ctl.tabory.dao.hibernate.services.ServiceManager;
import pl.iachoo.ctl.tabory.dao.hibernate.vo.CompositionVO;
import pl.iachoo.ctl.tabory.dao.hibernate.vo.VagonVO;
import pl.iachoo.ctl.tabory.ui.editors.compositions.CompositionSelection;
import pl.iachoo.ctl.tabory.ui.editors.vagons.VagonSelection;
import pl.iachoo.ctl.tabory.ui.editors.vagons.composites.VagonTableSectionPart;
import pl.iachoo.ctl.tabory.ui.properties.Messages;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionListener;
import pl.iachoo.ctl.tabory.ui.selection.ISelectionProvider;

public class CompositionDetailsSectionPart extends SectionPart implements
		ISelectionProvider<CompositionSelection> {

	private final Logger logg = Logger
			.getLogger(CompositionDetailsSectionPart.class);

	private Text detailCompositionName;
	private VagonTableSectionPart allVagonTableSectionPart;
	private VagonTableSectionPart selectedVagonTableSectionPart;

	private ISelectionListener<CompositionSelection> selectionListener;

	private CompositionSelection compositionSelection;
	private VagonSelection allVagonSelection;
	private VagonSelection selectedVagonSelection;
	private Button btnRemoveVagon;
	private Button btnAddVagon;
	private Composite buttonComposite;
	private Button btnSave;
	private Button btnCancel;

	/**
	 * Create the SectionPart.
	 * 
	 * @param parent
	 * @param toolkit
	 * @param style
	 */
	public CompositionDetailsSectionPart(Composite parent, FormToolkit toolkit,
			int style) {
		super(parent, toolkit, style);
		allVagonSelection = new VagonSelection();
		selectedVagonSelection = new VagonSelection();
		createClient(getSection(), toolkit);
		initActions();
	}

	/**
	 * Fill the section.
	 */
	private void createClient(Section section, FormToolkit toolkit) {
		section.setText(Messages.getString("compositions.details.name"));
		Composite container = toolkit.createComposite(section);

		section.setClient(container);
		container.setLayout(new GridLayout(2, false));

		Label lblNewLabel = toolkit.createLabel(container,
				Messages.getString("compositions.details.compositionname"),
				SWT.NONE);
		lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));

		detailCompositionName = new Text(container, SWT.BORDER);
		GridData gd_detailCompositionName = new GridData(SWT.LEFT, SWT.CENTER,
				true, false, 1, 1);
		gd_detailCompositionName.widthHint = 100;
		detailCompositionName.setLayoutData(gd_detailCompositionName);
		toolkit.adapt(detailCompositionName, true, true);

		Label label = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2,
				1));
		toolkit.adapt(label, true, true);

		Composite composite = toolkit.createComposite(container, SWT.NONE);
		composite.setLayout(new GridLayout(3, false));
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true,
				2, 1));
		toolkit.paintBordersFor(composite);

		allVagonTableSectionPart = new VagonTableSectionPart(composite,
				toolkit,
				Messages.getString("compositions.details.duallist.left"),
				false, true);
		Section sctnvagonseditortabletitle = allVagonTableSectionPart
				.getSection();
		sctnvagonseditortabletitle.setLayoutData(new GridData(SWT.LEFT,
				SWT.FILL, false, true, 1, 1));
		toolkit.paintBordersFor(sctnvagonseditortabletitle);

		Composite composite_1 = toolkit.createComposite(composite, SWT.NONE);
		composite_1.setLayout(new GridLayout(1, false));
		composite_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				true, 1, 1));
		toolkit.paintBordersFor(composite_1);

		btnAddVagon = toolkit.createButton(composite_1, "", SWT.FLAT);
		btnAddVagon.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		btnAddVagon.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_REDO));

		btnRemoveVagon = toolkit.createButton(composite_1, "", SWT.FLAT);
		btnRemoveVagon.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		btnRemoveVagon.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_TOOL_UNDO));

		selectedVagonTableSectionPart = new VagonTableSectionPart(composite,
				toolkit,
				Messages.getString("compositions.details.duallist.right"),
				false, true);
		Section sctnvagonseditortabletitle_1 = selectedVagonTableSectionPart
				.getSection();
		sctnvagonseditortabletitle_1.setLayoutData(new GridData(SWT.LEFT,
				SWT.FILL, false, true, 1, 1));
		toolkit.paintBordersFor(sctnvagonseditortabletitle_1);
		new Label(composite, SWT.NONE);
		new Label(composite, SWT.NONE);
		new Label(composite, SWT.NONE);

		buttonComposite = toolkit.createComposite(container, SWT.NONE);
		buttonComposite.setLayout(new GridLayout(2, false));
		buttonComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false,
				false, 2, 1));
		toolkit.paintBordersFor(buttonComposite);

		btnSave = toolkit.createButton(buttonComposite,
				Messages.getString("common.ok"), SWT.FLAT);
		btnSave.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_ETOOL_SAVE_EDIT));

		btnCancel = toolkit.createButton(buttonComposite,
				Messages.getString("common.cancel"), SWT.FLAT);
		btnCancel.setImage(PlatformUI.getWorkbench().getSharedImages()
				.getImage(ISharedImages.IMG_ELCL_REMOVE));
	}

	private void initActions() {
		btnAddVagon.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				performAddVagonAction(e);
			}

		});
		btnRemoveVagon.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				performRemoveVagonAction(e);
			}

		});
		btnSave.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				performSaveAction(e);
			}

		});
		btnCancel.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				performCancelAction(e);
			}

		});
		allVagonTableSectionPart
				.addSelectionListener(new ISelectionListener<VagonSelection>() {
					@Override
					public void selectionChanged(VagonSelection selection) {
					}
				});
		selectedVagonTableSectionPart
				.addSelectionListener(new ISelectionListener<VagonSelection>() {
					@Override
					public void selectionChanged(VagonSelection selection) {
					}
				});
	}

	private void performAddVagonAction(SelectionEvent e) {
		VagonVO selectedVagon = allVagonSelection.getSelectedVagon();
		CompositionVO selectedComposition = compositionSelection
				.getSelectedComposition();
		if (selectedComposition == null) {
			selectedComposition = new CompositionVO();
		}
		Set<VagonVO> vagonVOs = selectedComposition.getVagonVOs();
		if (vagonVOs == null) {
			vagonVOs = new LinkedHashSet<VagonVO>();
		}
		vagonVOs.add(selectedVagon);
		selectedComposition.setVagonVOs(vagonVOs);
		compositionSelection.setSelectedComposition(selectedComposition);
		ArrayList<VagonVO> listVagons = new ArrayList<VagonVO>(vagonVOs);
		Collections.sort(listVagons);
		selectedVagonSelection.setListVagons(listVagons);
		selectedVagonTableSectionPart.setSelection(selectedVagonSelection);
	}

	private void performRemoveVagonAction(SelectionEvent e) {
		VagonVO selectedVagon = selectedVagonSelection.getSelectedVagon();
		List<VagonVO> listVagons = selectedVagonSelection.getListVagons();
		if (selectedVagon != null && listVagons != null) {
			listVagons.remove(selectedVagon);
		}
		selectedVagonSelection.setListVagons(listVagons);
		compositionSelection.getSelectedComposition().setVagonVOs(
				new HashSet<VagonVO>(listVagons));
		selectedVagonTableSectionPart.setSelection(selectedVagonSelection);
	}

	private void performSaveAction(SelectionEvent e) {
		CompositionVO selectedComposition = compositionSelection
				.getSelectedComposition();
		if (selectedComposition == null) {
			selectedComposition = new CompositionVO();
		}
		selectedComposition.setInternalId(detailCompositionName.getText());
		Set<VagonVO> vagonVOs = new HashSet<VagonVO>();
		List<VagonVO> listVagons = selectedVagonSelection.getListVagons();
		if (listVagons != null) {
			for (VagonVO vagon : listVagons) {
				vagonVOs.add(vagon);
			}
		}
		selectedComposition.setVagonVOs(vagonVOs);
		compositionSelection.setSelectedComposition(selectedComposition);
		try {
			ServiceManager.getCompositionService().saveOrUpdateComposition(
					selectedComposition);
		} catch (Exception ex) {
			logg.error(ex.getMessage(), ex);
		}
		performCancelAction(e);
	}

	private void performCancelAction(SelectionEvent e) {
		compositionSelection.setEditing(false);
		compositionSelection.setNew(false);
		List<CompositionVO> allCompositions;
		try {
			allCompositions = ServiceManager.getCompositionService()
					.getAllCompositions();
			compositionSelection.setListComposition(allCompositions);
		} catch (Exception ex) {
			logg.error(ex.getMessage(), ex);
		}
		selectionListener.selectionChanged(compositionSelection);
	}

	private void setEnabled(boolean isEnabled) {
		detailCompositionName.setEnabled(isEnabled);
		selectedVagonTableSectionPart.setEnabled(isEnabled);
		allVagonTableSectionPart.setEnabled(isEnabled);
		btnAddVagon.setEnabled(isEnabled);
		btnRemoveVagon.setEnabled(isEnabled);
		if (compositionSelection.isEditing() || compositionSelection.isNew()) {
			buttonComposite.setVisible(true);
			btnSave.setEnabled(true);
			btnCancel.setEnabled(true);
		} else {
			buttonComposite.setVisible(false);
		}
	}

	@Override
	public CompositionSelection getSelection() {
		return compositionSelection;
	}

	@Override
	public void setSelection(CompositionSelection selection) {
		compositionSelection = selection;
		allVagonSelection.setListVagons(selection.getListAllVagons());
		if (selection.getSelectedComposition() != null) {
			selectedVagonSelection.setListVagons(new ArrayList<VagonVO>(
					selection.getSelectedComposition().getVagonVOs()));
			detailCompositionName.setText(selection.getSelectedComposition()
					.getInternalId());
		} else {
			selectedVagonSelection.setListVagons(new ArrayList<VagonVO>());
			detailCompositionName.setText("");
		}
		allVagonTableSectionPart.setSelection(allVagonSelection);
		selectedVagonTableSectionPart.setSelection(selectedVagonSelection);
		CompositionVO selectedComposition = compositionSelection
				.getSelectedComposition();
		if (selection.isEditing() || selection.isNew()) {
			setEnabled(true);
		} else {
			setEnabled(false);
		}
		if (selectedComposition != null) {
			detailCompositionName.setText(selectedComposition.getInternalId());
		}
	}

	@Override
	public void addSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
		selectionListener = listner;
	}

	@Override
	public void removeSelectionListener(
			ISelectionListener<CompositionSelection> listner) {
		selectionListener = null;
	}
}
